package com.pxt.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class MyView extends View {
    private Paint paint = null;
    private Bitmap pic = null;

    private float dx = 0;
    private float dy = 0;
    private float rotate = 0;
    private float scale = 1;

    private final int MOVE = 1;
    private final int ZOOM = 2;
    private final int NONE = 0;
    private int mode = NONE;

    private float old_x_down = 0;
    private float old_y_down = 0;
    private float old_translate_x = 0;
    private float old_translate_y = 0;

    private PointF pointF = new PointF();

    private float oldScale = 1;
    private float oldDist = 1f;
    private float oldAngle = 0;
    private float oldRotation = 0;

    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context) {
        pic = BitmapFactory.decodeResource(getResources(), R.mipmap.pic);
        Matrix matrix = new Matrix();
        pic = Bitmap.createBitmap(pic, 0, 0, pic.getWidth(), pic.getHeight(), matrix, true);
        paint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.translate(dx, dy);
        canvas.scale(scale, scale, pic.getWidth() / 2, pic.getHeight() / 2);
        canvas.rotate(rotate, pic.getWidth() / 2, pic.getHeight() / 2);
        canvas.drawBitmap(pic, 0.0f, 0.0f, paint);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mode = MOVE;
                old_x_down = event.getX();
                old_y_down = event.getY();
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                mode = ZOOM;
                oldDist = spacing(event);
                oldAngle = angle(event);
                midPoint(pointF, event);
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == ZOOM) {
                    //缩放
                    float newDist = spacing(event);
                    float newScale = newDist / oldDist * oldScale;

                    scale = newScale;

                    oldDist = newDist;
                    oldScale = newScale;

                    float newAngle = angle(event);
                    float newRotation = newAngle - oldAngle + oldRotation;
                    rotate = newRotation;

                    oldRotation = newRotation;
                    oldAngle = newAngle;
                } else if (mode == MOVE) {
                    dx = event.getX() - old_x_down + old_translate_x;
                    dy = event.getY() - old_y_down + old_translate_y;

                    old_x_down = event.getX();
                    old_y_down = event.getY();
                    old_translate_x = dx;
                    old_translate_y = dy;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                break;
        }
        return true;
    }

    // 触碰两点间距离
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 取手势中心点
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    // 取旋转角度
    private float angle(MotionEvent event) {
        double delta_x = (event.getX(0) - event.getX(1));
        double delta_y = (event.getY(0) - event.getY(1));
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }
}
